// HTTP model definition
// Copyright 2006 (C) Ralph Thomas

#ifndef HTTP_MODEL_H
#define HTTP_MODEL_H

#include <model/model.h>
#include <model/internal/receiverHelper.h>
#include <model/internal/url.h>
#include <model/internal/sort.h>
#include <model/attributeInfo.h>
#include <model/attributeNames.h>
#include <boost/thread/recursive_mutex.hpp>
#include <toolkit/icon.h>
#include <map>

namespace model {
	//
	/// The httpModel can fetch data over HTTP. The current implementation
	/// uses libcurl on Linux and wininet on Windows to perform fetches.
	//
	class httpModel : public model {
		typedef std::map<std::string, httpModel*>	modelMap;
		typedef boost::recursive_mutex			mutex;
		typedef mutex::scoped_lock			lock;
		static modelMap	_modelMap;	///< Already created HTTP models
		static mutex	_modelMutex;	///< Lock for _modelMap.
		unsigned int	_refCount;	///< Reference count of model.
		receiverHelper	_receivers;	///< All subscribed.
		std::string	_theUrl;	///< URL to fetch.
		unsigned int	_error;		///< Current error code.
		std::string	_contents;	///< The contents of the model.
		std::string	_type;		///< MIME type of the model.
		mutable bool	_loadQueued;	///< Is a load queued up?
		mutable mutex	_mutex;		///< For loader threads.
		//
		// httpModel( const std::string& theUrl )
		//
		/// Create a new httpModel from the given URL.
		/// 
		/// \param	theUrl	the URL to load data from.
		//
		httpModel( const std::string& theUrl );
		//
		// ~httpModel()
		// 
		/// Virtual destructor; should only be invoked by release()
		/// when the reference count reaches zero.
		//
		virtual ~httpModel();
		//
		// std::string _getParentUrl() const
		// 
		/// Return the URL of this model's parent.
		///
		/// \return	the URL of this model's parent.
		//
		std::string _getParentUrl() const;
	  public:
		//
		// void load( std::string type, std::string data )
		//
		/// Called by the loader thread when it has loaded the data.
		///
		/// \param	type	the MIME type of this data.
		/// \param	data	the data of this model.
		//
		void load( const std::string& type, const std::string& data );
		//
		// static model* fromString( std::string serialized )
		//
		/// Create an httpModel from the given string. If the
		/// httpModel cannot be created then zero is returned,
		/// otherwise the httpModel is returned.
		///
		/// \param	serialized	the URL to create an
		///				http model from.
		//
		static model* fromString( const std::string& serialized );
		//
		// from model/model.h
		//
		virtual model* retain() const;
		virtual void release();
		virtual void subscribe( receiver* r );
		virtual void unsubscribe( const receiver* r );
		virtual adobe::value_t getAttribute( const std::string&
			attrName ) const;
		virtual void setAttribute( const std::string& attrName,
			const adobe::value_t& val );
		virtual adobe::value_t execute( const std::string& action,
			const adobe::value_t& arg );
	};
};

#endif

